﻿using CommonServiceLocator;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Threading;
using HandyControl.Data;
using RemoteTool.Business.Tools;
using RemoteTool.Business.Tools.Helper;
using RemoteTool.Data;
using RemoteTool.Data.Model;
using RemoteTool.IRepositories;
using RemoteTool.Service;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using MessageBox = HandyControl.Controls.MessageBox;

namespace RemoteTool.ViewModel.Controls
{
    internal class RemoteControlViewModel : ViewModelBase
    {
        private bool _busyState = false;
        public bool BusyState
        {
            get => _busyState;
            set
            {
                Set(nameof(BusyState), ref _busyState, value);
            }
        }

        private bool _showInfo = false;
        public bool ShowInfo
        {
            get => _showInfo;
            set
            {
                Set(nameof(ShowInfo), ref _showInfo, value);
            }
        }

        private DeviceInfo _currentDevInfo;
        /// <summary>
        /// 当前选择的设备信息
        /// </summary>
        public DeviceInfo CurrentDevInfo { get => _currentDevInfo; set => Set<DeviceInfo>(ref _currentDevInfo, value); }

        private string _searchMsg;
        public string SearchMsg { get => _searchMsg; set { Set<string>(ref _searchMsg, value); } }
        private string _keyword;
        public string Keyword { get => _keyword; set { Set(nameof(Keyword), ref _keyword, value); } }
        private int _pageIndex = 1;
        public int PageIndex { get => _pageIndex; set { Set(nameof(PageIndex), ref _pageIndex, value); } }

        private int _totalPageCount = 0;
        public int TotalPageCount { get => _totalPageCount; set { _totalPageCount = value; RaisePropertyChanged(nameof(TotalPageCount)); } }

        private readonly IRepository<DeviceInfo> repository;
        private readonly IWebApiService webApiService;

        public RelayCommand Loaded { get; }
        public RelayCommand ReloadCmd { get; }
        public RelayCommand SearchCmd { get; }
        public RelayCommand UploadCmd { get; }
        public RelayCommand DownloadCmd { get; }
        /// <summary>
        /// 导出当前查询记录
        /// </summary>
        public RelayCommand ExportCmd { get; }
        public RelayCommand<FunctionEventArgs<int>> PageUpdatedCmd { get; }

        public RelayCommand<DeviceInfo> CopyDevInfoCmd { get; }
        public RelayCommand AddDevice { get; }
        public RelayCommand<DeviceInfo> AddByModel { get; }
        public RelayCommand<DeviceInfo> DeleteCmd { get; }
        public RelayCommand<DeviceInfo> DetailCmd { get; }
        public RelayCommand SaveExitCmd { get; }

        public ObservableCollection<DeviceInfo> DeviceList { get; set; } = new ObservableCollection<DeviceInfo>();
        public DataService DataService { get; }

        private const int pageSize = 10;
        private RefAsync<int> totalNumber = 0;

        public RemoteControlViewModel(DataService dataService, IRepository<DeviceInfo> repository, IWebApiService webApiService)
        {
            DataService = dataService;
            this.repository = repository;
            this.webApiService = webApiService;

            Loaded = new RelayCommand(LoadedHandler);
            ReloadCmd = new RelayCommand(ReloadCmdHandler);
            SearchCmd = new RelayCommand(SearchCmdHandler);
            CopyDevInfoCmd = new RelayCommand<DeviceInfo>(CopyDevInfoCmdHandler);
            AddDevice = new RelayCommand(AddDeviceHandler);
            AddByModel = new RelayCommand<DeviceInfo>(AddByModelHandler);
            DeleteCmd = new RelayCommand<DeviceInfo>(DeleteCmdHandler);
            DetailCmd = new RelayCommand<DeviceInfo>(DetailCmdHandler);
            SaveExitCmd = new RelayCommand(SaveExitCmdHandler);
            UploadCmd = new RelayCommand(UploadCmdHandler);
            DownloadCmd = new RelayCommand(DownloadCmdHandler);
            ExportCmd = new RelayCommand(ExportCmdHandler);
            PageUpdatedCmd = new RelayCommand<FunctionEventArgs<int>>(PageUpdatedCmdHandler);

            Messenger.Default.Register<DeviceInfo>(this, MessageToken.AddDeviceInfo, (info) =>
            {
                if (!repository.AnyAsycn(x => x.ToDeskId.Replace(" ", "") == info.ToDeskId.Replace(" ", "")
                && x.OraySunId.Replace(" ", "") == info.OraySunId.Replace(" ", "")).Result)
                {
                    repository.Insert(info);
                    DispatcherHelper.CheckBeginInvokeOnUI(() => { DeviceList.Add(info); });
                }
            }, true);

        }

        private async void PageUpdatedCmdHandler(FunctionEventArgs<int> info)
        {
            try
            {
                BusyState = true;
                totalNumber = 0;
                var list = await repository.FindPageLatestAsycn(info.Info, pageSize, totalNumber);
                TotalPageCount = (int)Math.Ceiling((double)totalNumber / pageSize);
                DeviceList.Clear();
                list.ForEach(p => DeviceList.Add(p));
                BusyState = false;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLine($"加载设备信息异常->{ex.Message}");
            }
        }

        private async void ExportCmdHandler()
        {
            var exportList = new List<DeviceInfo>();
            BusyState = true;
            try
            {
                if (string.IsNullOrEmpty(Keyword))
                {
                    exportList = await repository.FindAllAsycn();
                }
                else
                {
                    var main = ServiceLocator.Current.GetInstance<MainViewModel>();
                    if (main.IsLogin)
                    {
                        var result = await webApiService.SearchDeviceInfoAsync(Keyword);
                        if (result != null && result.success && result.data.Count > 0)
                        {
                            exportList.AddRange(result.data);
                        }
                    }
                    var list = await repository.FindAllAsycn(Keyword);
                    foreach (var item in list)
                    {
                        if (!exportList.Exists(p => p.Equals(item)))
                        {
                            exportList.Add(item);
                        }
                    }
                }
                
                if (exportList.Count > 0)
                {
                    DataTable dt = new DataTable();
                    dt.Columns.Add("记录的唯一标识");
                    dt.Columns.Add("设备序列号");
                    dt.Columns.Add("所属项目名称");
                    dt.Columns.Add("设备名称");
                    dt.Columns.Add("ToDeskId");
                    dt.Columns.Add("ToDeskPsw");
                    dt.Columns.Add("ToDesk点击计数");
                    dt.Columns.Add("OraySunId");
                    dt.Columns.Add("OraySunPsw");
                    dt.Columns.Add("OraySun点击计数");
                    dt.Columns.Add("最近连接时间");
                    dt.Columns.Add("创建者名字");
                    dt.Columns.Add("创建时间");

                    //写入数值
                    for (int i = 0; i < exportList.Count; i++)
                    {
                        List<object> values = new List<object>();
                        values.Add(exportList[i].GuidCode);
                        values.Add(exportList[i].DeviceSerialNo);
                        values.Add(exportList[i].ProjectName);
                        values.Add(exportList[i].DeviceName);
                        values.Add(exportList[i].ToDeskId);
                        values.Add(exportList[i].ToDeskPsw);
                        values.Add(exportList[i].ToDeskCount);
                        values.Add(exportList[i].OraySunId);
                        values.Add(exportList[i].OraySunPsw);
                        values.Add(exportList[i].OraySunCount);
                        values.Add(exportList[i].LastTime);
                        values.Add(exportList[i].CreatorName);
                        values.Add(exportList[i].CreateTime);
                        dt.Rows.Add(values.ToArray());
                    }
                    dt.ExportToExcel("标签数据记录表");
                }
                else
                {
                    MessageBox.Show($"当前条件没有数据可供导出！");
                }

            }
            catch (Exception ex)
            {
                LogHelper.WriteLine($"查询所有设备信息异常->{ex.Message}");
            }
            BusyState = false;
        }

        private async void DownloadCmdHandler()
        {
            BusyState = true;
            var result = await webApiService.DownloadDeviceInfosAsync();
            BusyState = false;
            if (result.success)
            {
                SortedDictionary<string, DeviceInfo> dictionary = new SortedDictionary<string, DeviceInfo>();
                foreach (var item in result.data)
                {
                    if (dictionary.ContainsKey(item.ProjectName) == false)
                        dictionary.Add(item.ProjectName, item);
                }
                DispatcherHelper.CheckBeginInvokeOnUI(() =>
                {
                    SearchMsg = $"总共下载到{result.data.Count}条结果，包含项目{dictionary.Keys.Count}个！";
                    DeviceList.Clear();
                    result.data.ForEach(p => DeviceList.Add(p));
                    if (!DataService.SearchNames.ToList().Exists(p => p.Keyword == Keyword))
                    {
                        DataService.SearchNames.Add(new keywordInfo() { Keyword = Keyword, Count = 1, LatestTime = DateTime.Now });
                    }
                });
                await Task.Run(() =>
                {
                    result.data.ForEach(p =>
                    {
                        if (p.CreateTime == null) { p.CreateTime = DateTime.Now; }
                        if (string.IsNullOrEmpty(p.CreatorName)) { p.CreatorName = Environment.UserName; }
                        if (string.IsNullOrEmpty(p.GuidCode)) { p.GuidCode = Guid.NewGuid().ToString(); }
                        Messenger.Default.Send<DeviceInfo>(p, MessageToken.AddDeviceInfo);
                    });
                });
            }
            else
            {
                MessageBox.Show($"下载设备信息失败->{result.message}");
            }
        }

        private async void UploadCmdHandler()
        {
            BusyState = true;
            var list = await repository.FindAllAsycn();
            foreach (var item in list)
            {
                //设备信息本地创建的情况下需要补充该字段，兼容旧版本
                if (string.IsNullOrEmpty(item.GuidCode))
                {
                    item.GuidCode = Guid.NewGuid().ToString();
                    repository.Update(item);
                }
                //设备信息本地创建的情况下需要补充该字段
                if (string.IsNullOrEmpty(item.CreatorName))
                {
                    var main = ServiceLocator.Current.GetInstance<MainViewModel>();
                    item.CreatorName = main.UserName;
                    repository.Update(item);
                }
            }
            var result = await webApiService.UploadDeviceInfosAsync(list);
            if (result.success)
            {
                MessageBox.Show($"上传设备信息成功->{result.message}");
            }
            else
            {
                MessageBox.Show($"上传设备信息失败->{result.message}");
            }
            BusyState = false;
        }

        private void ReloadCmdHandler()
        {
            if (string.IsNullOrEmpty(Keyword?.Replace(" ", "")))
            {
                Keyword = string.Empty;
                LoadedHandler();
            }
        }

        private async void LoadedHandler()
        {
            try
            {
                BusyState = true;
                totalNumber = 0;
                var list = await repository.FindPageLatestAsycn(1, pageSize, totalNumber);
                TotalPageCount = (int)Math.Ceiling((double)totalNumber / pageSize);
                DeviceList.Clear();
                list.ForEach(p => DeviceList.Add(p));
                SearchMsg = $"查询到所有记录{totalNumber}条";
                BusyState = false;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLine($"加载设备信息异常->{ex.Message}");
            }

        }

        private async void SearchCmdHandler()
        {
            if (string.IsNullOrEmpty(Keyword))
            {
                DispatcherHelper.CheckBeginInvokeOnUI(() => { MessageBox.Show("搜索关键词不能为空！"); });
            }
            else
            {
                BusyState = true;
                var listAll = new List<DeviceInfo>();
                var main = ServiceLocator.Current.GetInstance<MainViewModel>();
                if (main.IsLogin)
                {
                    var result = await webApiService.SearchDeviceInfoAsync(Keyword);
                    if (result != null && result.success && result.data.Count > 0)
                    {
                        listAll.AddRange(result.data);
                    }
                }
                totalNumber = 0;
                var list = await repository.FindAllAsycn(Keyword, 1, pageSize, totalNumber);
                TotalPageCount = (int)Math.Ceiling((double)totalNumber / pageSize);
                foreach (var item in list)
                {
                    if (!listAll.Exists(p => p.Equals(item)))
                    {
                        listAll.Add(item);
                    }
                }
                if (listAll.Count > 0)
                {
                    SortedDictionary<string, DeviceInfo> dictionary = new SortedDictionary<string, DeviceInfo>();
                    foreach (var item in listAll)
                    {
                        if (dictionary.ContainsKey(item.ProjectName) == false)
                            dictionary.Add(item.ProjectName, item);
                    }
                    DispatcherHelper.CheckBeginInvokeOnUI(() =>
                    {
                        SearchMsg = $"总共查询到{listAll.Count}条结果，包含项目{dictionary.Keys.Count}个！";
                        DeviceList.Clear();
                        listAll.ForEach(p => DeviceList.Add(p));
                        if (!DataService.SearchNames.ToList().Exists(p => p.Keyword == Keyword))
                        {
                            DataService.SearchNames.Add(new keywordInfo() { Keyword = Keyword, Count = 1, LatestTime = DateTime.Now });
                        }
                    });
                }
                else
                {
                    DispatcherHelper.CheckBeginInvokeOnUI(() => { SearchMsg = $"关键词{Keyword}没有查询到结果！"; });
                }

                BusyState = false;
            }
        }
        /// <summary>
        /// 更新设备信息
        /// </summary>
        private async void SaveExitCmdHandler()
        {
            BusyState = true;
            var msg = string.Empty;
            var main = ServiceLocator.Current.GetInstance<MainViewModel>();
            if (main.IsLogin)
            {
                var result = await webApiService.ModifyDeviceInfoAsync(CurrentDevInfo);
                if (result != null) { msg = result.message; }
                if (result.success)
                {
                    LogHelper.WriteLog($"{CurrentDevInfo.DeviceName}服务器更新完成");
                }
                else
                {
                    LogHelper.WriteLog($"{CurrentDevInfo.DeviceName}服务器更新失败->{result.message}");
                    //MessageBox.Show($"{CurrentDevInfo.DeviceName}服务器更新失败->{result.message}");
                }
            }
            repository.Update(CurrentDevInfo);
            MessageBox.Show($"{CurrentDevInfo.DeviceName}本地更新完成  服务器->{msg}");
            ShowInfo = false;
            BusyState = false;
        }

        private void DetailCmdHandler(DeviceInfo info)
        {
            DispatcherHelper.CheckBeginInvokeOnUI(() =>
            {
                CurrentDevInfo = info;
                ShowInfo = !ShowInfo;
            });
        }

        private async void DeleteCmdHandler(DeviceInfo info)
        {
            if (MessageBox.Show("亲，确定要删除该设备信息吗？", "注意", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                BusyState = true;
                var main = ServiceLocator.Current.GetInstance<MainViewModel>();
                if (main.IsLogin)
                {
                    var result = await webApiService.DeleteDeviceInfoAsync(info.GuidCode);
                    //if (result.success)
                    //{
                    //    MessageBox.Show("服务器删除成功！");
                    //    //LogHelper.WriteLog($"{info.DeviceName}删除成功！");
                    //}
                    //else
                    //{
                    //    MessageBox.Show($"{result.message}");
                    //    //LogHelper.WriteLog($"{info.DeviceName}删除失败！->{result.message}");
                    //}
                    MessageBox.Show($"服务器删除结果->{result?.message}");
                }
                repository.Delete(info);
                DispatcherHelper.CheckBeginInvokeOnUI(() => { DeviceList.Remove(info); });
                BusyState = false;
            }
        }

        private void AddByModelHandler(DeviceInfo obj)
        {
            if (AssemblyHelper.CreateInternalInstance($"Window.AddDeviceWindow") is System.Windows.Window window)
            {
                window.Owner = Application.Current.MainWindow;
                var deviceInfo = obj.ToObjectCopy();
                deviceInfo.ClearAll();
                var context = new AddDeviceWindowViewModel() { DevInfo = deviceInfo, CloseAction = () => { window.Close(); } };
                window.Tag = deviceInfo.ToObjectCopy();//可能因为combox双向绑定导致text为空，这里主动设置一下初始化值，控件加载后重新设置
                window.DataContext = context;
                window.ShowDialog();
            }
        }

        private void AddDeviceHandler()
        {
            if (AssemblyHelper.CreateInternalInstance($"Window.AddDeviceWindow") is System.Windows.Window window)
            {
                window.Owner = Application.Current.MainWindow;
                window.DataContext = new AddDeviceWindowViewModel() { CloseAction = () => { window.Close(); } };
                window.ShowDialog();
            }
        }

        private void CopyDevInfoCmdHandler(DeviceInfo info)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"项目名称：{info.ProjectName}");
            sb.AppendLine($"设备名称：{info.DeviceName}");
            sb.AppendLine($"ToDesk服务器账号：{info.ToDeskId}");
            sb.AppendLine($"ToDesk服务器密码：{info.ToDeskPsw}");
            sb.AppendLine($"向日葵服务器账号：{info.OraySunId}");
            sb.AppendLine($"向日葵服务器密码：{info.OraySunPsw}");
            //其他程序占用会导致异常
            //Clipboard.SetText(sb.ToString());
            //调用系统方法更好，可以绕过一些程序占用导致的异常
            Win32Helper.SetText(sb.ToString());
        }

    }
}
